/**
 * Object reacting to user input.
 * @constructor
 */
Controller = function() {};

/**
 * Method called after page is loaded.
 * @public
 */
Controller.init = function() {
  $("#button_login").
      off("click").
      on("click", Controller.login_);
  $("#button_logout").
      off("click").
      on("click", Controller.logout_);
  log("Controller: Application initialized.");
};

/**
 * Bind events to objects in subjects table.
 * @private
 */
Controller.bindTableEvents_ = function() {
  Controller.bindEventsHeaders_();
  Controller.bindEventsSubjects_();
  Controller.bindEventsTests_();
  Controller.bindEventsRunning_();
  Controller.bindEventsAddTest_();
  Controller.bindEventsDatepicker_();
  Controller.bindEventsAddRunningTeacher_();
  Controller.bindEventsActivateRunning_();
  Controller.bindEventSubmitSolution_();
  log("Controller: Events bound.");
};

/** @private */
Controller.login_ = function() {
  var name = $("#name").val();
  var password = $("#password").val();
  Model.loginValidation(name, password, function() {
    $("#logged_as").text(name);
    View.transitionLogin();
    Controller.bindTableEvents_();
    log("Controller: Login event finished.");
  });
}

/** @private */
Controller.logout_ = function() {
  Model.sendSubjectsToServer();
  $("#name").val("");
  $("#password").val("");
  $("#logged_as").text("");
  log("Controller: Logout event finished.");
}

/** @private */
Controller.bindEventsHeaders_ = function() {
  $(".table_header div").
      off("click").
      on("click", function() {
        var ascending = $(this).hasClass("sorted_desc") ||
                        !$(this).hasClass("sorted_asc");
        var byArray = $(this).attr("id").split("_");
        Model.refreshSubjects(byArray[byArray.length - 1], ascending, true,
                              Controller.bindTableEvents_);
      });
} 

/** @private */
Controller.bindEventsSubjects_ = function() {
  $(".subject_row").
      off("click").
      on("click", function() {
        var idArray = $(this).attr("id").split("_");
        Model.toggleSubject(idArray[idArray.length - 1],
                            Controller.bindEventsTests_);
      });
}

/** @private */
Controller.bindEventsTests_ = function() {
  $(".test_row").
      off("click").
      on("click", function() {
        var idArray = $(this).attr("id").split("_");
        Model.toggleTest(idArray[idArray.length - 1],
                         Controller.bindEventsRunning_);
      });
  Controller.bindEventsAddTest_();
  Controller.bindEventsDatepicker_();
}

/** @private */
Controller.bindEventsRunning_ = function() {
  $(".running_row").
      off("click").
      on("click", function() {
        var idArray = $(this).attr("id").split("_");
        Model.toggleRunning(idArray[idArray.length - 1],
                            Controller.bindEventsAddMessage_);
      });
  Controller.bindEventsAddRunningTeacher_();
  Controller.bindEventsActivateRunning_();
  Controller.bindEventSubmitSolution_();
}

Controller.bindEventsDatepicker_ = function(){
    $("*[id^=subject_options_deadline_]").datepicker();
}

Controller.bindEventsAddTest_ = function() {
  $("*[id^=subject_options_add_test_]").
      off("click").
      on("click", function() {
    var idArray = $(this).attr("id").split("_");
    var id = idArray[idArray.length - 1];
    var deadline = $("#subject_options_deadline_" + id).val();
    if(moment(deadline, 'DD/MM/YYYY').isValid()){
      View.errorShow("subject_options_add_test_" + id, "wrong_time");
    }
    deadline = moment(deadline, 'DD/MM/YYYY').format('YYYY-MM-DD 23:59:59');
    Model.addTest({
        "name": $("#subject_options_name_" + id).val(),
        "deadline": deadline,
        "compilationCommand": $("#subject_options_compilation_command_" + id).val(),
        "runningCommand": $("#subject_options_running_command_" + id).val(),
        "solutionFilename": $("#subject_options_solution_filename_" + id).val()
      },
      id,
      Controller.bindTableEvents_);
  });
}

Controller.bindEventsAddRunningTeacher_ = function() {
  $("*[id^=test_options_add_test_file_]").
      off("click").
      on("click", function() {
    var idArray = $(this).attr("id").split("_");
    var testId = idArray[idArray.length - 1];
    $("#test_options_test_id_" + testId).val(testId);
    var formData = new FormData(document.getElementById("test_options_form_" + testId));
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/add_file', true);
    xhr.addEventListener("load", function(){
      try{
        var res = JSON.parse(xhr.response);
      }catch(SyntaxError){
        res = {"error": "unknown"};
      }
      Model.addRunning("test_options_activate_test_" + testId, res.error, Controller.bindTableEvents_);
    });
    xhr.send(formData);
  });
}

Controller.bindEventsActivateRunning_ = function() {
  $("*[id^=test_options_activate_test_]").
    off("click").
    on("click", function() {
      var idArray = $(this).attr("id").split("_");
      var testId = idArray[idArray.length - 1];
      Model.activateTest(testId, Controller.bindTableEvents_);
  });
}

Controller.bindEventSubmitSolution_ = function(){
  $("*[id^=test_options_submit_solution_]").
      off("click").
      on("click", function() {
    var idArray = $(this).attr("id").split("_");
    var testId = idArray[idArray.length - 1];
    $("#test_options_test_id_" + testId).val(testId);
    var formData = new FormData(document.getElementById("test_options_form_" + testId));
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '/run_test', true);
    View.spinnerShow('test_options_submit_solution_' + testId);
    xhr.addEventListener("load", function() {
      try {
        var res = JSON.parse(xhr.response);
      } catch(SyntaxError) {
        res = {"error": "unknown"};
      }
      Model.addRunning("test_options_submit_solution_" + testId, res.error, Controller.bindTableEvents_);
    });
    xhr.send(formData);
  });
}

Controller.bindEventsAddMessage_ = function() {
  $("*[id^=running_options_comment_button_]").
      off("click").
      on("click", function() {
    var idArray = $(this).attr("id").split("_");
    var runId = idArray[idArray.length - 1];
    Model.addMessage({
        "content": $("#running_options_comment_" + runId).val(),
      },
      runId,
      Controller.bindTableEvents_);
  });
}
